<template>
  <el-card class="card-box">
    <div class="header">
      <h2>维修完成审批</h2>
    </div>

    <el-form inline class="filter-bar">
      <el-form-item label="设备ID:">
        <el-select
          v-model="searchParams.serialNumber"
          filterable remote clearable reserve-keyword
          placeholder="请输入设备ID"
          :remote-method="fetchSerialSuggestions"
          :loading="loadingSerialNumbers"
          class="input-short"
        >
          <el-option
            v-for="item in serialNumberOptions"
            :key="item"
            :label="item"
            :value="item"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="申请人ID:">
        <el-input
          v-model.number="searchParams.applicantId"
          placeholder="请输入申请人ID"
          type="number"
          clearable
          class="input-short"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="search">
          <el-icon><Search /></el-icon>搜索
        </el-button>
        <el-button @click="resetSearch">
          <el-icon><Refresh /></el-icon>重置
        </el-button>
      </el-form-item>
    </el-form>

    <div class="responsive-table-container">
      <table class="custom-table">
        <thead>
          <tr>
            <th>编号</th>
            <th>设备ID</th>
            <th>申请人ID</th>
            <th>故障描述</th>
            <th>状态</th>
            <th>维修人员ID</th>
            <th>申请时间</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="item in repairRequestList" :key="item.id">
            <td>{{ item.id }}</td>
            <td>{{ item.serialNumber }}</td>
            <td>{{ item.applicantId }}</td>
            <td class="truncate">{{ item.faultDescription }}</td>
            <td>
              <el-tag :type="item.status === '已完成' ? 'success' : item.status === '维修完毕' ? 'warning' : 'info'">
                {{ getStatusTypeLabel(item.status) }}
              </el-tag>
            </td>
            <td>{{ item.assignedToId }}</td>
            <td>{{ formatDateTime(item.requestTime) }}</td>
            <td>
              <el-button
                type="primary"
                @click="showDetail(item)"
                class="view-btn"
              >
                <el-icon><View /></el-icon>查看详情
              </el-button>
            </td>
          </tr>
          <tr v-if="repairRequestList.length === 0">
            <td colspan="8" class="text-center py-4">
              <el-empty description="暂无数据" />
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    <div class="pagination-container">
      <el-pagination
        v-model:current-page="pageNum"
        v-model:page-size="pageSize"
        :page-sizes="[5, 10, 20]"
        layout="total, sizes, prev, pager, next, jumper"
        background
        :total="total"
        @size-change="onSizeChange"
        @current-change="onCurrentChange"
      />
    </div>

    <!-- 详情对话框 -->
    <el-dialog 
      v-model="detailDialogVisible" 
      :title="`维修申请详情 #${currentRequest?.id}`" 
      width="800px"
      class="compact-dialog"
    >
      <div v-if="currentRequest" class="detail-content">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="设备ID">{{ currentRequest.serialNumber }}</el-descriptions-item>
          <el-descriptions-item label="申请人ID">{{ currentRequest.applicantId }}</el-descriptions-item>
          <el-descriptions-item label="维修人员ID">{{ currentRequest.assignedToId }}</el-descriptions-item>
          <el-descriptions-item label="申请时间">{{ formatDateTime(currentRequest.requestTime) }}</el-descriptions-item>
          <el-descriptions-item label="状态">
            <el-tag :type="currentRequest.status === '已完成' ? 'success' : 'warning'">
              {{ getStatusTypeLabel(currentRequest.status) }}
            </el-tag>
          </el-descriptions-item>
        </el-descriptions>

        <el-divider>
          <el-icon><Notebook /></el-icon> 故障描述
        </el-divider>
        <div class="repair-notes">{{ currentRequest.faultDescription }}</div>

        <el-divider>
          <el-icon><List /></el-icon> 维修记录
        </el-divider>
        <div v-if="currentProcess" class="process-detail">
          <el-descriptions :column="2" border>
            <el-descriptions-item label="维修人员ID">{{ currentProcess.repairerId }}</el-descriptions-item>
            <el-descriptions-item label="开始时间">{{ formatDateTime(currentProcess.startTime) }}</el-descriptions-item>
            <el-descriptions-item label="结束时间">{{ formatDateTime(currentProcess.endTime) }}</el-descriptions-item>
            <el-descriptions-item label="总费用">¥{{ currentProcess.totalCost?.toFixed(2) || '0.00' }}</el-descriptions-item>
          </el-descriptions>

          <div class="repair-notes">
            <h4>维修说明:</h4>
            <p>{{ currentProcess.repairNotes }}</p>
          </div>

          <td>
  <template v-if="currentProcess.repairFileUrl">
    <template v-if="isImageFile(currentProcess.repairFileUrl)">
      <el-popover
        placement="left"
        trigger="hover"
        :width="325"
        popper-class="image-popover"
      >
        <template #reference>
          <img
            :src="currentProcess.repairFileUrl"
            class="thumbnail-img"
            alt="缩略图"
            @click="downloadFile(currentProcess.repairFileUrl)"
          />
        </template>
        <img :src="currentProcess.repairFileUrl" class="preview-img" alt="大图预览" />
      </el-popover>
      <a
        :href="currentProcess.repairFileUrl"
        :download="currentProcess.repairFileUrl.split('/').pop()"
        class="thumbnail-download"
        title="点击下载"
      />
    </template>
    <el-button
      v-else
      :icon="Download"
      type="primary"
      link
      @click="downloadFile(currentProcess.repairFileUrl)"
    >
      下载附件
    </el-button>
  </template>
  <span v-else class="no-attachment">无附件</span>
</td>
        </div>
        <div v-else class="no-process">
          <el-empty description="暂无维修记录" />
        </div>

        <el-divider>
          <el-icon><Box /></el-icon> 使用配件
        </el-divider>
        <div v-if="currentParts.length > 0" class="parts-list">
          <table class="custom-table">
            <thead>
              <tr>
                <th>配件名称</th>
                <th>数量</th>
                <th>单价</th>
                <th>总价</th>
                <th>状态</th>
                <th>凭证</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="part in currentParts" :key="part.id">
                <td>{{ part.partName }}</td>
                <td>{{ part.quantity }}</td>
                <td>¥{{ part.unitPrice?.toFixed(2) || '0.00' }}</td>
                <td>¥{{ (part.quantity * part.unitPrice)?.toFixed(2) || '0.00' }}</td>
                <td>
                  <el-tag :type="part.status === '已通过' ? 'success' : part.status === '已驳回' ? 'danger' : 'warning'">
                    {{ part.status }}
                  </el-tag>
                </td>
                <td>
  <template v-if="part.partFileUrl">
    <template v-if="isImageFile(part.partFileUrl)">
      <el-popover
        placement="left"
        trigger="hover"
        :width="325"
        popper-class="image-popover"
      >
        <template #reference>
          <img
            :src="part.partFileUrl"
            class="thumbnail-img"
            alt="缩略图"
            @click="downloadFile(part.partFileUrl)"
          />
        </template>
        <img :src="part.partFileUrl" class="preview-img" alt="大图预览" />
      </el-popover>
      <a
        :href="part.partFileUrl"
        :download="part.partFileUrl.split('/').pop()"
        class="thumbnail-download"
        title="点击下载"
      />
    </template>
    <el-button
      v-else
      :icon="Download"
      type="primary"
      link
      @click="downloadFile(part.partFileUrl)"
    >
      下载附件
    </el-button>
  </template>
  <span v-else class="no-attachment">无附件</span>
</td>
              </tr>
            </tbody>
          </table>
        </div>
        <div v-else class="no-parts">
          <el-empty description="未使用配件" />
        </div>

        <div class="action-buttons">
          <el-button
            type="primary"
            @click="confirmComplete"
            :loading="isConfirming"
            :disabled="!currentProcess || currentParts.some(part => part.status !== '已通过')"
            class="confirm-btn"
          >
            <el-icon><Check /></el-icon>确认完成维修
          </el-button>
        </div>
      </div>
    </el-dialog>
  </el-card>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { View, Check, Download, Notebook, List, Box } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import request from '@/utils/request'

// 定义类型
interface RepairRequest {
  id: number
  serialNumber: string
  applicantId: number
  faultDescription: string
  requestTime: string
  status: string
  assignedToId: number
}

interface RepairProcess {
  id: number
  repairRequestId: number
  repairerId: number
  startTime: string
  endTime: string
  repairNotes: string
  repairFileUrl: string
  totalCost: number
}

interface RepairPart {
  id: number
  repairProcessId: number
  partName: string
  quantity: number
  unitPrice: number
  totalPrice: number
  partFileUrl: string
  status: string
}

interface RepairRequestListResponse {
  current: number
  total: number
  pages: number
  size: number
  records: RepairRequest[]
}

interface RepairProcessListResponse {
  current: number
  total: number
  pages: number
  size: number
  records: RepairProcess[]
}

interface RepairPartListResponse {
  current: number
  total: number
  pages: number
  size: number
  records: RepairPart[]
}

// 定义常量
const statusTypeMap = {
  '待分配': '待分配',
  '已分配': '已分配',
  '维修完毕': '维修完毕',
  '已完成': '已完成'
} as const

const getStatusTypeLabel = (value: string): string => {
  return statusTypeMap[value as keyof typeof statusTypeMap] || '未知状态'
}

const repairApi = {
  getRepairRequestList: (params: any) => request<RepairRequestListResponse>({
    method: 'GET',
    url: '/repair/request/list',
    params
  }),

  getRepairProcessList: (params: any) => request<RepairProcessListResponse>({
    method: 'GET',
    url: '/repair/process/list',
    params
  }),

  getRepairPartList: (params: any) => request<RepairPartListResponse>({
    method: 'GET',
    url: '/repair/part/list',
    params
  }),

  confirmRepairCompleted: (repairRequestId: number) => request<string>({
    method: 'POST',
    url: '/repair/request/confirm-complete',
    params: { repairRequestId }
  }),

  getSerialSuggestions: (keyword: string) => request<string[]>({
    method: 'GET',
    url: '/device/serial/suggestions',
    params: { keyword }
  })
}

// 组件状态
const repairRequestList = ref<RepairRequest[]>([])
const searchParams = ref({
  status: '维修完毕',
  serialNumber: null as string | null,
  applicantId: null as number | null
})

const pageNum = ref(1)
const pageSize = ref(10)
const total = ref(0)

const detailDialogVisible = ref(false)
const currentRequest = ref<RepairRequest | null>(null)
const currentProcess = ref<RepairProcess | null>(null)
const currentParts = ref<RepairPart[]>([])
const isConfirming = ref(false)

// 设备ID搜索相关
const serialNumberOptions = ref<string[]>([])
const loadingSerialNumbers = ref(false)

// 生命周期
onMounted(() => {
  loadRepairRequests()
})

// 方法
const loadRepairRequests = async () => {
  try {
    const params = {
      page: pageNum.value,
      size: pageSize.value,
      ...searchParams.value
    }

  const filteredParams = Object.entries(params).reduce((acc, [key, value]) => {
    if (value !== null && value !== undefined && value !== '') {
      (acc as any)[key] = value;
    }
    return acc;
  }, {});
  console.log(filteredParams);

    const response = await repairApi.getRepairRequestList(params)
    repairRequestList.value = response.data.records
    total.value = response.data.total
  } catch (error) {
    ElMessage.error('获取维修申请列表失败')
    console.error(error)
  }
}

const fetchSerialSuggestions = async (query: string) => {
  if (query) {
    loadingSerialNumbers.value = true
    try {
      const res = await repairApi.getSerialSuggestions(query)
      serialNumberOptions.value = res.data
    } catch {
      ElMessage.error('获取设备序列号失败')
    } finally {
      loadingSerialNumbers.value = false
    }
  } else {
    serialNumberOptions.value = []
  }
}

const showDetail = async (request: RepairRequest) => {
  try {
    currentRequest.value = request
    
    // 加载维修过程
    const processResponse = await repairApi.getRepairProcessList({
      page: 1,
      size: 1,
      repairRequestId: request.id
    })
    
    if (processResponse.data.records.length > 0) {
      currentProcess.value = processResponse.data.records[0]
      
      // 加载配件记录
      const partsResponse = await repairApi.getRepairPartList({
        page: 1,
        size: 100,
        repairProcessId: currentProcess.value.id
      })
      
      currentParts.value = partsResponse.data.records
    } else {
      currentProcess.value = null
      currentParts.value = []
    }
    
    detailDialogVisible.value = true
  } catch (error) {
    console.error('获取详情失败:', error)
    ElMessage.error('获取详情失败')
  }
}

const confirmComplete = async () => {
  if (!currentRequest.value) return
  
  try {
    isConfirming.value = true
    
    if (!currentProcess.value) {
      ElMessage.warning('该维修申请没有维修记录，不能完成')
      return
    }
    
    if (currentParts.value.length > 0 && currentParts.value.some(part => part.status !== '已通过')) {
      ElMessage.warning('存在未通过审批的配件，不能完成维修')
      return
    }
    
    await repairApi.confirmRepairCompleted(currentRequest.value.id)
    
    ElMessage.success('维修已完成')
    detailDialogVisible.value = false
    loadRepairRequests()
  } catch (error) {
    console.error('完成维修失败:', error)
    ElMessage.error('完成维修失败')
  } finally {
    isConfirming.value = false
  }
}

const downloadFile = (url: string) => {
  if (!url) {
    ElMessage.warning('没有可下载的附件')
    return
  }
  
  const link = document.createElement('a')
  link.href = url
  link.target = '_blank'
  link.download = url.split('/').pop() || 'attachment'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

const formatDateTime = (datetime: string) => {
  if (!datetime) return ''
  return new Date(datetime).toLocaleString()
}

const search = () => {
  pageNum.value = 1
  loadRepairRequests()
}

const resetSearch = () => {
  searchParams.value = {
    status: '维修完毕',
    serialNumber: null,
    applicantId: null
  }
  pageNum.value = 1
  loadRepairRequests()
}

const onSizeChange = (size: number) => {
  pageSize.value = size
  loadRepairRequests()
}

const onCurrentChange = (num: number) => {
  pageNum.value = num
  loadRepairRequests()
}

const isImageFile = (url: string): boolean => {
  return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(url)
}

</script>
<style lang="scss" scoped>
.card-box {
  width: 100%;
  max-width: 100%;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}

.header {
  padding: 0.8rem 1.2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #e6eaf0;
  background-color: #f7f9fc;
  
  h2 {
    font-weight: 600;
    font-size: 1.4rem;
    color: #333;
    user-select: none;
    margin: 0;
  }
}

.filter-bar {
  padding: 0.8rem 1.2rem;
  background-color: #fafbfc;
  border-bottom: 1px solid #e6eaf0;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  overflow-x: auto;
  white-space: nowrap;
  gap: 0.8rem;

  .el-form-item {
    margin-bottom: 0 !important;
    flex-shrink: 0;
    
    label {
      font-weight: 500;
      color: #606266;
      font-size: 0.9rem;
    }
    
    .input-short {
      width: 150px;
    }
  }

  .el-button {
    height: 32px;
    font-weight: 500;
    padding: 0 12px;
    flex-shrink: 0;
  }
}

.responsive-table-container {
  overflow-x: auto;
  background: #fff;
  padding: 0.8rem;
}

.custom-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0 6px;
  font-size: 0.9rem;

  thead tr {
    background-color: #f5f7fa;
    color: #606266;
    font-weight: 600;
    user-select: none;
  }

  th, td {
    padding: 8px 12px;
    text-align: left;
    vertical-align: middle;
    white-space: nowrap;
  }

  th {
    font-size: 0.85rem;
  }

  tbody tr {
    background-color: #fff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
    transition: background-color 0.2s ease;

    &:hover {
      background-color: #f4f9ff;
    }
  }

  .truncate {
    max-width: 180px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .view-btn {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 6px 10px;
  }
}

.pagination-container {
  background-color: #fafbfc;
  padding: 0.8rem;
  border-top: 1px solid #e6eaf0;
  display: flex;
  justify-content: center;
}

.text-center {
  text-align: center;
}

.py-4 {
  padding-top: 1rem;
  padding-bottom: 1rem;
}

/* 详情对话框样式 */
.compact-dialog {
  :deep(.el-dialog__header) {
    padding: 16px 20px;
    border-bottom: 1px solid #ebeef5;
    margin-right: 0;
  }
  
  :deep(.el-dialog__title) {
    font-size: 18px;
    font-weight: 500;
    color: #303133;
  }
  
  :deep(.el-dialog__body) {
    padding: 20px;
  }
}

.detail-content {
  .repair-notes {
    padding: 16px;
    background-color: #f8fafc;
    border-radius: 8px;
    margin-bottom: 16px;
    line-height: 1.6;
    white-space: pre-line;
  }

  .process-detail {
    margin-bottom: 20px;
    
    .repair-notes {
      h4 {
        margin: 0 0 8px 0;
        font-size: 16px;
      }
      
      p {
        margin: 0;
        white-space: pre-line;
        line-height: 1.6;
      }
    }
    
    .file-list {
      display: flex;
      flex-wrap: wrap;
      gap: 12px;
      margin-top: 12px;
    }
  }

  .no-process, .no-parts {
    margin: 20px 0;
  }

  .parts-list {
    margin-bottom: 24px;
    
    .custom-table {
      thead tr {
        background-color: #f5f7fa;
        color: #606266;
      }
      
      tbody tr:hover {
        background-color: #f5f7fa;
      }
    }
  }

  .action-buttons {
    display: flex;
    justify-content: center;
    margin-top: 24px;
    padding-top: 16px;
    border-top: 1px solid #ebeef5;
    
    .confirm-btn {
      padding: 10px 24px;
      display: flex;
      align-items: center;
      gap: 6px;
    }
  }
}

.download-btn {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* 响应式调整 */
@media (max-width: 1200px) {
  .filter-bar {
    gap: 0.6rem;
    
    .input-short {
      width: 140px;
    }
  }
  
  .custom-table {
    font-size: 0.85rem;
    
    th, td {
      padding: 6px 8px;
    }
  }
}

@media (max-width: 992px) {
  .header {
    padding: 0.6rem 1rem;
    
    h2 {
      font-size: 1.2rem;
    }
  }
  
  .filter-bar {
    padding: 0.6rem 1rem;
  }
  
  .responsive-table-container {
    padding: 0.6rem;
  }
}
.file-preview-wrapper {
  margin-top: 8px;
  display: flex;
  align-items: center;
  position: relative;
}

.file-preview {
  position: relative;
  display: inline-block;
  cursor: pointer;
  width: 80px;
  height: 80px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
  background-color: #f5f7fa;
  text-align: center;
  line-height: 80px;
  color: #606266;
  font-size: 12px;
  transition: border-color 0.3s ease;
}

.file-preview:hover {
  border-color: #409eff;
}

.preview-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.file-name {
  display: block;
  padding: 0 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-hover-preview {
  position: absolute;
  top: 0;
  z-index: 20;
  display: none;
  background: white;
  padding: 6px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  min-width: 120px;
  max-width: 200px;
  max-height: 200px;
  white-space: normal;
}

.left-preview {
  right: 100%; // 左侧显示
  margin-right: 10px;
}

.zoom-img {
  width: 100%;
  height: auto;
  max-height: 180px;
  object-fit: contain;
}

.zoom-text {
  color: #303133;
  font-size: 14px;
  word-break: break-all;
}

.file-preview:hover .file-hover-preview {
  display: block;
}
.attachment-thumbnail {
  display: inline-block;
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  vertical-align: middle;
}

.thumbnail-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 4px;
  object-fit: cover;
  cursor: pointer;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease;
}

.thumbnail-img:hover {
  transform: scale(1.1);
}

.attachment-thumbnail {
  display: inline-block;
  width: 40px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  vertical-align: middle;
}

.thumbnail-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 4px;
  object-fit: cover;
  cursor: pointer;
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease;
}

.thumbnail-img:hover {
  transform: scale(1.1);
}
.thumbnail-img {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  object-fit: cover;
  cursor: zoom-in;
  transition: transform 0.2s ease;
  margin-right: 4px;
  vertical-align: middle;
}

.thumbnail-img:hover {
  transform: scale(1.1);
}

.thumbnail-download {
  display: inline-block;
  width: 0;
  height: 0;
  overflow: hidden;
}
.thumbnail-img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
  border: 1px solid #ddd;
}

.image-popover {
  padding: 0 !important;
  background-color: transparent !important;
  box-shadow: none !important;
  border: none !important;
}

.preview-img {
  width: 300px; // 放大图片
  height: auto;
  max-height: 400px;
  display: block;
  object-fit: contain;
  border: none;
  border-radius: 0;
  background: transparent;
}

.thumbnail-download {
  display: none; // 你也可以用按钮代替
}
</style>